package com.ltkj.common.core.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

/**
 * 时间工具类
 *
 * @author ruoyi
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static Date getNowStringToDate() {
        return parseDate(dateTimeNow(YYYY_MM_DD));
    }

    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算时间差
     *
     * @param endDate   最后时间
     * @param startTime 开始时间
     * @return 时间差（天/小时/分钟）
     */
    public static String timeDistance(Date endDate, Date startTime) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startTime.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    // 计算相差多少天
    public static long timeDistanceDay(Date endDate, Date startTime) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startTime.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day;
    }

    /**
     * 统计两个时间的时间差
     * two-one
     * 相差几秒几毫秒type]:0,天，1：小时，2：分钟，3：秒，4毫秒
     */
    public static long getDistanceDateTime(Date one, Date two,int type) {
        long day = 0;//天数差
        long hour = 0;//小时数差
        long min = 0;//分钟数差
        long second=0;//秒数差
        long diff=0 ;//毫秒差
        String result = "";
        final Calendar c = Calendar.getInstance();
        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        c.setTime(one);
        long time1 = one.getTime();
        long time2 = two.getTime();
        diff = time2 - time1;
        day = diff / (24 * 60 * 60 * 1000);
        hour = (diff / (60 * 60 * 1000) - day * 24);
        min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
        second = diff/1000;
        System.out.println("day="+day+" hour="+hour+" min="+min+" ss="+second%60+" SSS="+diff%1000);
        String daystr = day%30+"天";
        String hourStr = hour%24+"小时";
        String minStr = min%60+"分";
        String secondStr = second%60+"秒";
        if(type==0){
            return day%30;
        }else if(type==1){
            return hour%24;
        } else if(type==2){
            return min%60;
        }else if(type==3){
            return second;
        }else if(type==4){
            return diff;
        }
        return diff;
    }


    /**
     * 增加 LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor) {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 增加 LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor) {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 获取 两个时间内 全部日期
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return {@link List}<{@link String}>
     */
    public static List<String> getAscDateList(Date startDate, Date endDate) {

        Instant instant = startDate.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();

        // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
        LocalDate localstartDate = instant.atZone(zoneId).toLocalDate();

        Instant instantEnd = endDate.toInstant();
        ZoneId zoneIdEnd = ZoneId.systemDefault();

        // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
        LocalDate localendDate = instantEnd.atZone(zoneIdEnd).toLocalDate();


        List<String> result = new ArrayList<>();
        if (localendDate.compareTo(localstartDate) < 0) {
            return result;
        }
        while (true) {
            result.add(localstartDate.toString());
            if (localstartDate.compareTo(localendDate) >= 0) {
                break;
            }
            localstartDate = localstartDate.plusDays(1);
        }
        return result;
    }

    public static List<String> getSevenDate() {
        List<String> dateList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 7; i++) {
            Date date = DateUtils.addDays(new Date(), +i);
            String formatDate = sdf.format(date);
            dateList.add(formatDate);
        }

        return dateList;
    }
    public static List<String> getSevenDate(Date datei) {
        List<String> dateList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 7; i++) {
            Date date = DateUtils.addDays(datei, +i);
            String formatDate = sdf.format(date);
            dateList.add(formatDate);
        }

        return dateList;
    }
    /**
     * 获取当前日期是星期几<br>
     *
     * @param date
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(String dateString) {
        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        String pattern = "yyyy-MM-dd";
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = dateFormat.parse(dateString);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Calendar cal = Calendar.getInstance();

        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    public static int getCompareToDate(Date date) {


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String datef = format.format(date);
        String dateend = format.format(DateUtils.getNowDate());

        int compareTo = 0;
        try {
            Date date1 = format.parse(datef);
            Date date2 = format.parse(dateend);

            compareTo = date1.compareTo(date2);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }


        return compareTo;
    }
    public static int getCompareToDateTime(Date date) {


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datef = format.format(date);
        String dateend = format.format(DateUtils.getNowDate());

        int compareTo = 0;
        try {
            Date date1 = format.parse(datef);
            Date date2 = format.parse(dateend);

            compareTo = date1.compareTo(date2);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }


        return compareTo;
    }

    /*
     * @description:
     * @author: gushaoliang
     * @date: 2023/9/16 15:47
     * @param: [date：时间, field：年月日时分秒参考Calendar, type，0加,1减,count数字]
     * @return: java.util.Date
     **/
    public static Date timeProcess(Date date, int field, int count) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(date);
        rightNow.add(field, count);
        // rightNow.add(Calendar.MINUTE, -10); //减10分钟
        // rightNow.add(Calendar.HOUR,1);//加一个小时
        //rightNow.add(Calendar.HOUR, 14);// 加14个小时，测试能不能加到明天，能不能加到下个月（结果是都可以,而且不受30天、31天的影响）
        // rightNow.add(Calendar.DAY_OF_MONTH,1);//加一天
        // rightNow.add(Calendar.MONTH,1);//加一个月
        Date dt1 = rightNow.getTime();
        return dt1;
    }
    /**
     * 比较两个时间的大小
     * @param source 当前时间
     * @param traget 需要比较的时间
     * @param type   日期格式
     * @return
     */
    public static int dateCompare(Date source, Date traget) {
        Integer b = -1;
        try {

            long ret = source.getTime() - traget.getTime();

            if (source.getTime() == traget.getTime()) {
                System.out.println("两个时间相等");
                b = 0;
            } else if (source.getTime() > traget.getTime()) {
                System.out.println("当前时间晚于" + traget);
                b = 1;
            } else if (source.getTime() < traget.getTime()) {
                System.out.println("当前时间早于" + traget);
                b = 2;
            }
        } catch (Exception e) {
            e.getMessage();
        }
        return b;
    }
    public static Date getStartTime(Date date) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(date);
        todayStart.set(Calendar.HOUR, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    public static Date getEndTime(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.setTime(date);
        todayEnd.set(Calendar.HOUR, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 0);
        return todayEnd.getTime();
    }

    public static Date getDateTime(Date date, Time time)  {
        SimpleDateFormat ds = new SimpleDateFormat("yyyy-MM-dd");
        String format = ds.format(date);
        SimpleDateFormat dsTime = new SimpleDateFormat("HH:mm:ss");
        String formatTime = dsTime.format(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setLenient(false);//sdf.setLenient(false);的目的是禁止SimpleDateFormat的自动计算功能，如果日期不合格自动报错。

        Date testTime = null;//拼接时，注意日期末尾与时间开头的空格，需要空出来保持格式才正确通过
        try {
            testTime = sdf.parse(format+" "+formatTime);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        // Timestamp timeVal=new Timestamp(testTime.getTime());
        //
        // System.out.println(timeVal);

        return testTime;

    }
    public static boolean getDateOnStarOrEnd(Date date, Date starDate,Date endDate)  {

        boolean after = date.after(starDate);
        boolean before = date.before(endDate);
        if (after && before) {
            System.out.println("在区间里");
            return true;

        }else{
            System.out.println("不在区间里");
            return false;
        }


    }
    /*
     * @description:计算两个时间差几天
     * @author: gushaoliang
     * @date: 2023/10/30 10:44
     * @param: [starDate, endDate]
     * @return: java.lang.Long
     **/
    public static long getDateOnStarOrEndDay(Date starDate,Date endDate)  {
        long diffInMilliseconds = Math.abs(endDate.getTime() - starDate.getTime());

        // 将毫秒数转换为天数
        long diffInDays = diffInMilliseconds / (24 * 60 * 60 * 1000);

        return diffInDays;


    }

    public static void main(String[] args) {
        System.out.println(getEndTime(new Date()));
    }

}
